package me.flyray.bsin.gateway.context;

import com.alipay.sofa.rpc.common.RpcConstants;

import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import me.flyray.bsin.context.LoginInfoContextHelper;
import me.flyray.bsin.domain.LoginUser;
import me.flyray.bsin.gateway.common.ApiResult;
import me.flyray.bsin.gateway.common.CommonConstants;
import me.flyray.bsin.gateway.utils.ServletUtils;
import me.flyray.bsin.utils.Pagination;

/**
 * @author ：bolei
 * @date ：Created in 2022/2/7 17:31
 * @description：请求上下文构建
 * @modified By：
 */
@Slf4j
@Component
public class BsinContextBuilder {


    /**
     * 构建登录信息Map
     *
     * @return 登录信息Map
     */
    public static Map<String, Object> buildLoginContextMap() {
        Map<String, Object> loginMap = Collections.emptyMap();
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        if (ObjectUtil.isNotEmpty(loginUser.getToken())) {
            loginMap = BeanUtil.beanToMap(loginUser);
        }
        // 获取完数据之后清除本地变量
        LoginInfoContextHelper.remove();
        return loginMap;
    }

    /**
     * 构建请求报文
     *
     * @param requestMap 请求参数
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> buildReqMessage(Map<String, Object> requestMap) {
        // 请求业务参数
        Map<String, Object> reqParam = new HashMap<>(requestMap.size());
        //处理登录信息
        Map<String, Object> loginMap = buildLoginContextMap();
        if (ObjectUtil.isNotEmpty(loginMap)) {
            reqParam.put("headers", loginMap);
        }
        // 业务参数
        Map<String, Object> bizParams = (Map<String, Object>) requestMap.get("bizParams");
        reqParam.putAll(bizParams);
        //处理分页信息
        Pagination pagination = MapUtil.get(requestMap, "pagination", Pagination.class);
        reqParam.put("pagination", pagination);
        reqParam.put("protocol", RpcConstants.PROTOCOL_TYPE_BOLT);
        reqParam.put("ipAddress", ServletUtils.getClientIP());
        return reqParam;
    }

    /**
     * 构建相应报文
     * 调用登录相关服务响应成功的生成相应的token
     * @param responseMap
     */
    public ApiResult buildResMessage(String serviceName, String methodName, Map<String, Object> responseMap) {
        //服务端异常捕获不到，暂时这样处理
        if (responseMap.get("data") == null) {
            return ApiResult.fail((String) responseMap.get("code"), (String) responseMap.get("message"));
        }
        // 平台管理员登录
        if ("login".equals(methodName) && "UserService".equals(serviceName)) {
            Map<String, Object> data = adminUserLogin(responseMap);
            return ApiResult.ok(data);
        }else if ("login".equals(methodName) && "PlatformService".equals(serviceName)) {
            // 节点登录
            Map<String, Object> data = merchantLogin(responseMap);
            return ApiResult.ok(data);
        }else if ("login".equals(methodName) && "MerchantService".equals(serviceName)) {
            // 商户登录
            Map<String, Object> data = merchantLogin(responseMap);
            return ApiResult.ok(data);
        }else if ("login".equals(methodName) && "CustomerService".equals(serviceName)) {
            // 会员注册登录
            Map<String, Object> data = memberLogin(responseMap);
            return ApiResult.ok(data);
        }else if ("registerOrLogin".equals(methodName) && "CustomerService".equals(serviceName)) {
                // 会员注册登录
                Map<String, Object> data = memberLogin(responseMap);
                return ApiResult.ok(data);
        } else if ("web3Login".equals(methodName) && "CustomerService".equals(serviceName)) {
            // web3会员注册登录
            Map<String, Object> data = web3Login(responseMap);
            return ApiResult.ok(data);
        }
        // 处理调用结果
        log.info(responseMap.toString());
        return ApiResult.ok(responseMap.get("data"), responseMap.get("pagination"));
    }

    /**
     * 运营平台用户登录
     */

    /**
     * dao用户登录
     */
    @SuppressWarnings("unchecked")
    private Map<String, Object> web3Login(Map<String, Object> loginResult) {

        Map<String, Object> data = (Map<String, Object>) loginResult.get("data");
        Map<String, Object> customerInfo = (Map<String, Object>) data.get("customerInfo");
        Map<String, Object> memberInfo = (Map<String, Object>) data.get("memberInfo");

        //bsin-server-huoyuanshequ
        String address = (String) loginResult.get("address");
        Map<String, Object> map = new HashMap<>();
        DateTime now = DateTime.now();
        DateTime newTime = now.offsetNew(DateField.HOUR, 24);
        //签发时间
        map.put(JWTPayload.ISSUED_AT, now);
        //过期时间
        map.put(JWTPayload.EXPIRES_AT, newTime);
        //生效时间
        map.put(JWTPayload.NOT_BEFORE, now);
        // 登录客户信息
        map.put("tenantId", MapUtils.getString(customerInfo, "tenantId"));
        map.put("customerNo",  MapUtils.getString(customerInfo, "customerNo"));
        map.put("username",  MapUtils.getString(customerInfo, "username"));
        map.put("merchantNo", MapUtils.getString(memberInfo, "merchantNo"));
        map.put("memberNo", MapUtils.getString(memberInfo, "serialNo"));
        data.put("token", JWTUtil.createToken(map, CommonConstants.JWT_SECRET.getBytes()));
        return data;
    }

    private Map<String, Object> merchantLogin(Map<String, Object> loginResult){

        Map<String, Object> data = (Map<String, Object>) loginResult.get("data");
        Map<String, Object> customerInfo = (Map<String, Object>) data.get("customerInfo");
        Map<String, Object> merchantInfo = (Map<String, Object>) data.get("merchantInfo");
        Map<String, Object> sysUser = (Map<String, Object>) data.get("sysUser");
        Map<String, Object> sysTenant = (Map<String, Object>) data.get("sysTenant");

        Map<String, Object> map = new HashMap<>();
        DateTime now = DateTime.now();
        DateTime newTime = now.offsetNew(DateField.HOUR, 24);
        //签发时间
        map.put(JWTPayload.ISSUED_AT, now);
        //过期时间
        map.put(JWTPayload.EXPIRES_AT, newTime);
        //生效时间
        map.put(JWTPayload.NOT_BEFORE, now);
        // 登录客户信息
        map.put("tenantId", MapUtils.getString(customerInfo, "tenantId"));
        map.put("tenantAppType", MapUtils.getString(sysTenant, "tenantAppType"));
        map.put("customerNo",  MapUtils.getString(customerInfo, "customerNo"));
        map.put("username",  MapUtils.getString(customerInfo, "username"));
        map.put("merchantNo", MapUtils.getString(merchantInfo, "serialNo"));
        map.put("userId", MapUtils.getString(sysUser, "userId"));
        map.put("userName", MapUtils.getString(sysUser, "userName"));
        map.put("userType", MapUtils.getString(customerInfo, "type"));
        data.put("token", JWTUtil.createToken(map, CommonConstants.JWT_SECRET.getBytes()));
        return data;
    }

    private Map<String, Object> memberLogin(Map<String, Object> loginResult){

        Map<String, Object> data = (Map<String, Object>) loginResult.get("data");
        Map<String, Object> customerInfo = (Map<String, Object>) data.get("customerInfo");
        Map<String, Object> memberInfo = (Map<String, Object>) data.get("memberInfo");

        Map<String, Object> map = new HashMap<>();
        DateTime now = DateTime.now();
        DateTime newTime = now.offsetNew(DateField.HOUR, 24);
        //签发时间
        map.put(JWTPayload.ISSUED_AT, now);
        //过期时间
        map.put(JWTPayload.EXPIRES_AT, newTime);
        //生效时间
        map.put(JWTPayload.NOT_BEFORE, now);
        // 登录客户信息
        map.put("tenantId", MapUtils.getString(customerInfo, "tenantId"));
        map.put("customerNo",  MapUtils.getString(customerInfo, "customerNo"));
        map.put("username",  MapUtils.getString(customerInfo, "username"));
        map.put("memberNo", MapUtils.getString(memberInfo, "serialNo"));
        map.put("userType", MapUtils.getString(customerInfo, "type"));
        data.put("token", JWTUtil.createToken(map, CommonConstants.JWT_SECRET.getBytes()));
        return data;
    }

    /**
     * 运营平台用户登录
     */
    private Map<String, Object> adminUserLogin(Map<String, Object> loginResult){

        Map<String, Object> data = (Map<String, Object>) loginResult.get("data");
        Map<String, Object> sysUser = (Map<String, Object>) data.get("sysUser");
        Map<String, Object> sysTenant = (Map<String, Object>) data.get("sysTenant");

        Map<String, Object> map = new HashMap<>();
        DateTime now = DateTime.now();
        DateTime newTime = now.offsetNew(DateField.HOUR, 24);
        //签发时间
        map.put(JWTPayload.ISSUED_AT, now);
        //过期时间
        map.put(JWTPayload.EXPIRES_AT, newTime);
        //生效时间
        map.put(JWTPayload.NOT_BEFORE, now);
        // 登录管理员信息
        map.put("tenantId", MapUtils.getString(sysUser, "tenantId"));
        map.put("tenantAppType", MapUtils.getString(sysTenant, "tenantAppType"));
        map.put("userId", MapUtils.getString(sysUser, "userId"));
        map.put("userName", MapUtils.getString(sysUser, "userName"));
        map.put("userType", MapUtils.getString(sysUser, "type"));
        map.put("createBy", MapUtils.getString(sysUser, "createBy"));
        map.put("updateBy", MapUtils.getString(sysUser, "updateBy"));
        data.put("token", JWTUtil.createToken(map, CommonConstants.JWT_SECRET.getBytes()));
        return data;
    }

}
